package org.lwjgl.demo.device;
import org.lwjgl.BufferUtils;

import java.io.File;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;

import static org.lwjgl.opengl.GL30.*;


/**
 * 纹理加载工具类
 *
 * @author zhoudy
 * @date 2025/10/30 21:59
 */
public class TextureLoader2 {
    
    /**
     * 加载纹理文件
     * @param filePath 纹理文件路径
     * @return 纹理ID
     */
    public static int loadTexture(String filePath) {
        // ==================== 新增：检查文件是否存在 ====================
        File file = new File(filePath);
        if (!file.exists()) {
            System.err.println("❌ 纹理文件不存在: " + filePath);
            return createFallbackTexture(); // 创建备用纹理
        }

        // 创建纹理ID
        int textureId = glGenTextures();
        glBindTexture(GL_TEXTURE_2D, textureId);
        
        // 设置纹理参数
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        
        // 加载图像
        IntBuffer width = BufferUtils.createIntBuffer(1);
        IntBuffer height = BufferUtils.createIntBuffer(1);
        IntBuffer channels = BufferUtils.createIntBuffer(1);
        
        // 注意：这里需要实际的文件路径，暂时使用生成的纹理
        // 在实际项目中，这里会使用 STBImage.stbi_load() 加载图片文件
        System.out.println("生成默认纹理代替文件加载: " + filePath);
        
        // 创建默认的棋盘格纹理（64x64）
        int texWidth = 64;
        int texHeight = 64;
        ByteBuffer imageData = BufferUtils.createByteBuffer(texWidth * texHeight * 3);
        
        // 生成棋盘格图案
        for (int y = 0; y < texHeight; y++) {
            for (int x = 0; x < texWidth; x++) {
                boolean isDark = ((x / 8) + (y / 8)) % 2 == 0;
                byte value = (byte) (isDark ? 100 : 200); // 深色和浅色
                
                imageData.put(value); // R
                imageData.put(value); // G
                imageData.put((byte) 255); // B（偏蓝色）
            }
        }
        imageData.flip();
        
        // 上传纹理数据
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texWidth, texHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, imageData);
        glGenerateMipmap(GL_TEXTURE_2D);
        
        glBindTexture(GL_TEXTURE_2D, 0);
        
        System.out.println("✅ 纹理创建成功, ID: " + textureId);
        return textureId;
    }
    
    /**
     * 创建纯色纹理
     * @param r 红色 (0-255)
     * @param g 绿色 (0-255)
     * @param b 蓝色 (0-255)
     * @return 纹理ID
     */
    public static int createSolidColorTexture(int r, int g, int b) {
        int textureId = glGenTextures();
        glBindTexture(GL_TEXTURE_2D, textureId);
        
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        
        // 创建1x1的纯色纹理
        ByteBuffer imageData = BufferUtils.createByteBuffer(3);
        imageData.put((byte) r);
        imageData.put((byte) g);
        imageData.put((byte) b);
        imageData.flip();
        
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, imageData);
        
        glBindTexture(GL_TEXTURE_2D, 0);
        return textureId;
    }

    /**
     * 创建备用纹理（当文件加载失败时使用）
     */
    private static int createFallbackTexture() {
        int textureId = glGenTextures();
        glBindTexture(GL_TEXTURE_2D, textureId);

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        // 创建明显的错误纹理（紫黑色棋盘格）
        int width = 64, height = 64;
        ByteBuffer imageData = BufferUtils.createByteBuffer(width * height * 3);

        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                boolean isPurple = ((x / 8) + (y / 8)) % 2 == 0;

                if (isPurple) {
                    imageData.put((byte) 255); // R
                    imageData.put((byte) 0);   // G
                    imageData.put((byte) 255); // B
                } else {
                    imageData.put((byte) 0);   // R
                    imageData.put((byte) 0);   // G
                    imageData.put((byte) 0);   // B
                }
            }
        }
        imageData.flip();

        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, imageData);
        glBindTexture(GL_TEXTURE_2D, 0);

        System.out.println("⚠️ 使用备用纹理");
        return textureId;
    }


    /**
     * 创建专门的镜面反射贴图
     */
    public static int createSpecularMap(int width, int height) {
        int textureId = glGenTextures();
        glBindTexture(GL_TEXTURE_2D, textureId);

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        // 创建高光贴图 - 边缘亮，中间暗
        ByteBuffer imageData = generateSpecularPattern(width, height);

        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, imageData);
        glGenerateMipmap(GL_TEXTURE_2D);

        glBindTexture(GL_TEXTURE_2D, 0);
        return textureId;
    }

    /**
     * 生成高光图案 - 边框高光效果
     */
    private static ByteBuffer generateSpecularPattern(int width, int height) {
        ByteBuffer buffer = BufferUtils.createByteBuffer(width * height * 3);

        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                // 计算到边缘的距离
                float distToEdgeX = Math.min(x, width - x) / (float) width;
                float distToEdgeY = Math.min(y, height - y) / (float) height;
                float distToEdge = Math.min(distToEdgeX, distToEdgeY);

                // 边缘区域高光更强
                float specularStrength;
                if (distToEdge < 0.1f) {
                    specularStrength = 1.0f; // 边框最强高光
                } else if (distToEdge < 0.2f) {
                    specularStrength = 0.7f; // 次边框中等高光
                } else {
                    specularStrength = 0.3f; // 中心区域较弱高光
                }

                byte value = (byte) (specularStrength * 255);
                buffer.put(value); // R
                buffer.put(value); // G
                buffer.put(value); // B
            }
        }
        buffer.flip();
        return buffer;
    }

    /**
     * 创建带图案的镜面反射贴图（木箱边框高光）
     */
    public static int createWoodenCrateSpecular(int width, int height) {
        int textureId = glGenTextures();
        glBindTexture(GL_TEXTURE_2D, textureId);

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        ByteBuffer imageData = generateWoodenCrateSpecularPattern(width, height);

        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, imageData);
        glGenerateMipmap(GL_TEXTURE_2D);

        glBindTexture(GL_TEXTURE_2D, 0);
        return textureId;
    }

    /**
     * 生成木箱风格的高光贴图 - 模拟木箱的金属边框
     */
    private static ByteBuffer generateWoodenCrateSpecularPattern(int width, int height) {
        ByteBuffer buffer = BufferUtils.createByteBuffer(width * height * 3);

        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                // 模拟木箱的金属边框高光
                boolean isBorder = (x < 10 || x > width - 10 || y < 10 || y > height - 10);
                boolean isMetalStrip = ((x % 32 < 4) || (y % 32 < 4));

                float specularStrength;
                if (isBorder) {
                    specularStrength = 1.0f; // 边框最强高光
                } else if (isMetalStrip) {
                    specularStrength = 0.8f; // 金属条高光
                } else {
                    specularStrength = 0.1f; // 木纹区域较弱高光
                }

                byte value = (byte) (specularStrength * 255);
                buffer.put(value); // R
                buffer.put(value); // G
                buffer.put(value); // B
            }
        }
        buffer.flip();
        return buffer;
    }
}